# 系统架构设计实践

> 让你的产品支棱起来



大家好，我是鱼皮。这篇文章我们来聊一个听起来很高大上、实则并不难的知识 —— **架构设计**。这是技术方向的朋友们必须要 **重点掌握** 的内容，也是做产品时在前期准备阶段必须要做的核心工作！

这篇文章中，我会结合自己做产品的实践经验，依次给大家分享：什么是架构设计？为什么要做架构设计？怎么做好架构设计？

无论你是用 Vibe Coding 做个人项目，还是想做一款真正的产品，掌握架构设计的方法都能让你的系统更稳定、更易扩展。



## 一、什么是架构设计？

想象一下，如果现在我们要盖一座摩天大楼，需要做哪些事？

是直接让工人去搬砖、叠砖么？还是让挖掘机来挖呀挖呀挖？

当然不是！

在盖楼之前，肯定会有一名建筑师，根据大楼的实际用途、地理位置、入驻需求等信息来绘制一份蓝图，蓝图上会规划大楼的外形、内部布局、结构细节等。

绘制好蓝图后，建筑师还要确定每层楼房的框架和支撑结构，确保它们足够稳定，不会说风一吹就塌了。

之后，建筑师还要根据大楼的实际用途和需求来规划每个楼层的用途，比如 B1 层卖小吃、1 层卖服装奢侈品等等。这些都是在大楼动工前确认好的，不会说等工人已经搬好砖后，上面临时决定 “这一层我们不盖了！”。

做软件（网站）开发也是一样，在我们 “码农” 实际动手写代码前，往往会有一个经验丰富的架构师，先绘制一份 **架构设计图** ，规划好整个系统的全貌、系统规模、系统的结构。

架构师还要将系统按照功能和需求划分为各个模块，比如商城系统划分为用户模块、商品模块、订单模块等。并且确定各个模块的作用和交互协作方式，保证整个系统能够正常运作。不会出现一个功能故障，整个系统全部瘫痪的情况。

有朋友可能会问了，那架构设计和之前讲过的技术选型有什么区别呢？

还是拿盖楼来举例，其实很好区分。架构设计是规划如何盖楼、每层楼怎么安排；而技术选型是在完成架构设计之后，选择具体用什么材料、工具或方法来完成盖楼。二者是相辅相成的。

用一句话来概括， **架构设计是构建稳固、可靠和可扩展系统的过程** 。

而我们熟知的岗位 “架构师”，就是负责完成系统架构设计，确保系统稳固、可靠、可扩展的人。

在大家的印象里，可能觉得架构师是很高大上的角色。但我个人认为，只要你能够独立完成一个系统的架构设计，能够把复杂的系统拆分为模块化、可扩展的组件，你就已经是架构师了。

> 所以 97 年就成为架构师还是有一定合理性的。



## 二、为什么要做架构设计？

其实从上面盖楼的例子中，相信大家已经能大致感受到架构设计的重要性了。

如果在盖楼前，不先设计好大楼的结构，那么就难以保证大楼的安全和稳定性，风一吹整层楼就塌了。同理，在开发网站前，如果不先设计好网站的整体架构（比如不添加防火墙），后面可能一遇到网络攻击，整个系统就都无法访问了。这是架构设计的核心目标：保证系统地 **稳定性、可靠性和可用性** 。换句话说，起码要让系统能跑。

> 不过没关系，系统和人只要有一个能跑就行。

进行架构设计的另一个重要原因，是系统的 **可扩展性** 。打个比方，建好的商场大楼非常受欢迎，我们想在盖好的大楼上再增加几层楼，那么必须在最初就确保大楼的结构可以支撑额外的重量、能够线性地往上叠加。而不是像下图一样：

![](https://pic.yupi.icu/1/image-20230711174331231.png)

同理，如果想要网站能够应对日益增长的用户量和新业务功能，也必须有一个良好的架构设计来支持。不要出现网站用户数增多后，网站无法访问的情况。

此外，好的架构设计也能够提升系统的性能和用户体验。比如在商场内，合理安排电梯数和电梯的位置，就能帮助用户快速到达想去的店铺；而网站的架构设计如果合理，比如用更少的分层完成同样的功能，那么就能更快地响应用户的操作。

总之，想要让网站像摩天大楼一样支棱起来，前期的架构设计是必要的！



## 三、怎么做好架构设计？

“能完成架构设计” 和 “能做好架构设计” 还是有很大的区别的，下面我会结合自己多年的学习经验、以及鱼聪明 AI 的架构设计，分享一些我认为的做好架构设计的关键。



### 掌握方法论

做好架构设计的前提是具备一定的理论知识。所谓方法论，是指前人通过总结和归纳形成的一套 **特定问题的解决方案** 。就像我们做数学题的时候知道套用公式来解题一样。

有很多对架构设计有帮助的方法论。比如初学编程时接触到的面向对象设计，软件开发基本原则、23 种经典设计模式、SOA 面向服务架构、DDD 领域驱动设计等等。掌握这些方法论背后的思想，是做好架构设计的 **前提** 。

举个例子，面向对象设计的五个基本原则 SOLID 中，有一点是 **单一职责原则** ，是指：一个类或模块应该有且只有一个单一的责任，每个类或模块应该只关注于一个特定的功能或职责。换句话说，每个模块应该只做好自己的事。

我们在进行鱼聪明 AI 网站的架构设计时，首先就遵循了单一职责原则，将系统 **按照功能拆分** 为用户模块、助手模块、对话模块、绘画模块、支付模块等。这样一来，当我们想要扩展对话相关的功能时，就不用改动助手模块的代码。也可以将不同的模块交给团队中不同的同学进行开发。

![](https://pic.yupi.icu/1/image-20230711192728792.png)



### 学习经典架构

前人栽树，后人乘凉。在我们没有能力自主设计一套架构前，不妨站在巨人的肩膀上，学习一些前人总结和实践过的经典架构。

简单举几个例子：



#### 1）分层架构

首先是最经典的分层架构，把系统分为多个不同的层，每一层都有特定的功能和职责，且只和自己的直接上层与直接下层 “打交道”。

比如开发 Java 企业级后端项目时常用的三层架构，将系统分为表示层、业务逻辑层、数据访问层。

表示层负责接受用户请求，把用户输入的参数传递给业务逻辑层进行处理，并返回数据、页面等内容给用户。

业务逻辑层负责处理复杂的业务逻辑，比如调用 AI 能力完成智能对话、再进行加工处理、调用数据访问层将结果存到数据库中，也是我们做系统主要开发的部分。

数据访问层负责操作底层的数据源，比如对数据库、文件、缓存等进行增删改查。

![](https://pic.yupi.icu/1/image-20230711194035810.png)

分层架构的适用性非常广泛，绝大多数企业级系统都可以把分层架构作为基础的架构设计。

计算机网络也是采用了经典的分层架构，OSI 七层参考模型中，把计算机网络自底向上分为了物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。每个层只处理特定的功能，比如数据传输、数据的路由；层与层之间通过接口（或者叫协议）进行通信。

我们的鱼聪明 AI 后端也是使用了分层架构，只不过在原有的三层架构基础上，在业务逻辑层和数据访问层之间又增加了 Manager 层（通用逻辑层），将业务逻辑层经常调用的 **公共逻辑** 提取出来，便于复用。



#### 2）微服务架构

微服务的 “微” 是相对于 “单体” 项目的概念。微服务架构是指将完整的大型系统拆分为多个微小的、自治的服务，每个服务都能独立部署、独立扩展和维护、互不影响，服务之间通过网络通信进行协作，从而实现原本大型系统的完整功能。

我们的鱼聪明 AI 就用到了微服务架构。前面也提到了，我们首先将系统按照功能划分为了多个模块。

但如果我们只是按逻辑划分出了这些模块，实际上所有的代码仍然部署在同一个项目中，打包后仍然是一个可执行文件。那么所有模块要么都在运行、要么都在宕机，本质上还是单体项目。一个服务崩了，可能导致整个项目都无法运行！

![](https://pic.yupi.icu/1/image-20230711200006355.png)

所以我们将部分重要模块（比如支付模块）的代码从原本项目中抽离，单独作为了一个服务，并且还启动了备份，从而保证了支付业务的稳定性。说什么也不能影响收入对不对~

![](https://pic.yupi.icu/1/image-20230711200339275.png)

能够实现微服务设计的框架也很多，比如 Java 的 Spring Cloud、Apache Dubbo 等。但是学习微服务更重要的是思想，即 **如何合理地拆分服务** 。

并不是所有的项目都要把所有功能都拆分成子服务的，像我们的鱼聪明 AI，也没有把用户模块和助手模块进行分离，原因是这两个模块的业务都不复杂、并且存在紧密的依赖，拆分后反而不利于维护了。



#### 3）事件驱动架构

在事件驱动架构中，各模块之间是通过事件（或者消息）的 **发布订阅模型** 进行通信的。

举个最简单的例子，有两个模块：支付模块和会员模块，当用户支付成功后，支付模块会给会员模块发送一个 “XX 用户支付成功” 的事件，会员模块收到这个时间后，给对应的用户开通会员即可。

![](https://pic.yupi.icu/1/image-20230711202025430.png)

但实际运用时，事件驱动架构往往会引入一个 **事件总线** ，相当于一个中介，负责集中收集和下发事件。

比如鱼聪明 AI 的对话功能和绘画功能就采用了事件驱动架构。当上游返回 AI 回复的消息或生成的图片后，会发送 “成功” 消息到事件总线，然后事件总线再将这些消息分别转发给对应的模块去处理。如下图：

![](https://pic.yupi.icu/1/image-20230711201650066.png)

这样一来，各模块之间就实现了解耦（互不影响）。假如后续我想新增多个对话模块，只要将该模块和事件总线建立连接即可，不会影响到其他模块的运行。



### 关注需求和痛点

我们在学习过程中接触到的项目，几乎都可以套用上述几种主流的架构。但具体应该如何做好架构设计，一定是要结合实际的需求和要解决的痛点去分析。

以鱼聪明 AI 为例，前面也提到了，我们首先就按照需求（功能）将系统拆分为了多个模块，然后将部分模块单独封装为服务进行独立部署。

但架构设计并没有到此结束，接下来分析下我们这个网站的痛点，主要是 “安全性” 和 “访问互通性” 这两个方面。



#### 安全性

根据我之前的翻车经历，网站上线后一定会遭受各种攻击！所以，我们在原有的分层架构基础上进行扩展，在表示层前增加高防服务器和 Nginx 防火墙，在表示层后增加了分布式限流和权限校验处理。

> 在表示层前添加集中的分布式限流和权限校验处理也是合理的，以实际需求为主。

改进过后的架构如图：

![](https://pic.yupi.icu/1/image-20230711203808233.png)

如果用户在短时间内用不法手段频繁向系统发送请求，那么在限流层就会被拦截，不会进行后续的业务逻辑处理。



#### 访问互通性

我们的 AI 绘画模块需要依赖第三方服务来完成部分功能，但是第三方服务并不支持访问跨地区访问，网络无法互通，怎么办呢？

这时，我们有 2 个方案可选：

1）把整个系统都放到第三方服务所在的地区去部署。如下图：

![](https://pic.yupi.icu/1/image-20230711205545871.png)

2）在 AI 绘画模块和第三方服务之间搭建一个代理，让代理帮忙发送和响应请求。如下图：

![](https://pic.yupi.icu/1/image-20230711210049633.png)

如果是你的话，会选择哪个呢？

方案 1 的好处是方便，但缺点也很明显，整个系统都移到其他地区，也就意味着原本地区的用户访问系统的所有功能，速度都会变慢。

方案 2 的好处是只需要改变 AI 绘画模块发送的请求地址信息，而系统的其他功能（比如查询用户信息）性能完全不变；缺点就是要搭建额外的服务、增加了实现成本。

最终，我们选择了方案 2 并改进了架构设计，增加一点实现成本来换取更好的用户体验。

通过这个例子，我想告诉大家的是：**没有绝对完美的架构设计** 。和技术选型一样，我们做架构设计的目标是寻找实际情况下的最优解。



### 超前思考

我们在做架构设计时，要养成超前思考的习惯，不能只针对现状，而是要提前预见系统未来可能的发展，预留足够的 **可扩展** 空间。

比如我们的鱼聪明 AI，虽然在最开始只有 100 个内测用户，但我们会按照 1 万个、甚至 10 万个用户的标准去设计系统，所以使用了分布式存储中间件而不是本地服务器来存储用户登录 Session；虽然早期历史对话消息数只积累了 5 万条，但我们提前设计了消息过期淘汰机制、并且将消息模块解耦，防止消息数达到百万、千万时影响系统的查询性能。

当然，超前思考也要有个度。要避免过度设计，不要提前去考虑绝对不可能发生的事情、不要提前去消耗远超增长的成本。



---



最后，要注意的是，**架构设计是一个持续的过程**，要根据业务的实际情况不断优化迭代。比如发现业务收益不高时，通过简化架构来降低成本；业务高速发展时，及时扩容服务来应对增长。



## 写在最后

架构设计是做好产品的重要基础。好的架构设计可以让系统更稳定、更易扩展、性能更好。

记住这几个关键点：

1. 架构设计要掌握基本的方法论和设计模式
2. 要学习经典架构，站在巨人的肩膀上
3. 要关注实际需求和痛点，而不是为了设计而设计
4. 要有超前思考的意识，预留扩展空间
5. 架构设计是持续优化的过程

在 Vibe Coding 时代，AI 可以帮你快速生成代码，但是系统的整体架构设计，仍然需要你自己的思考和规划。只要有架构设计的意识和足够的积累，人人都能成为架构师！




## 推荐资源

1）鱼皮 AI 导航网站：[AI 资源大全、最新 AI 资讯、免费 AI 教程](https://ai.codefather.cn)

2）编程导航学习圈：[学习路线、编程教程、实战项目、求职宝典、交流答疑](https://www.codefather.cn)

3）程序员面试八股文：[实习/校招/社招高频考点、企业真题解析](https://www.mianshiya.com)

4）程序员写简历神器：[专业模板、丰富例句、直通面试](https://www.laoyujianli.com)

5）1 对 1 模拟面试：[实习/校招/社招面试拿 Offer 必备](https://ai.mianshiya.com)
